
//============================变量 dom 双向绑定
/*
* 夕空 flashme.cn 2020-6-5
 var obj={}
 var watch = new watchdata();
 watch.inputevent(); //绑定input变化
 watch.domevent(); //绑定dom变化
 watch.setwatch(obj);
 obj.aaa="hello world!"
 <span ng-bind="aaa"></span>
*/

var watchdata = function (_ng) {
    //缓存
    let watchscope = {};
    let domeve = false;
    let ng = _ng||"ng-bind";
    //绑定变量
    return {
        setwatch: function (obj) {
            var than = this;
            let watchers = {};
            watchscope = obj;
            document.querySelectorAll("["+ng+"]").forEach(function (ele) {
                let attr = ele.getAttribute(ng)
                if(!watchscope[attr]){
                    watchscope[attr] = "";
                }
            })

            const propertys = Object.keys(watchscope);

            propertys.forEach(function (prop) {
                //不处理函数属性
                if ('function' == typeof watchscope[prop]) return;

                const propName = prop;
                // console.log(propName, watchscope[prop]);
                var dom = document.querySelector("*["+ng+"='" + prop + "']")
                dom.innerText = watchers[prop]||"";
                dom.value = watchers[prop]||"";
                //监听对象属性
                Object.defineProperty(watchscope, prop, {
                    //value: watchscope[prop],
                    configurable: true,
                    get: function () {
                        //console.log('get', prop, 'for', propName);
                        return watchers[propName];
                    },
                    set: function (value) {
                        //防止递归导致的栈溢出，先去掉监听的函数
                        domeve && document.removeEventListener('DOMCharacterDataModified', than.element);
                        domeve && document.removeEventListener('DOMNodeInserted', than.element);
                        watchers[prop] = value;
                        var dom = document.querySelector("*["+ng+"='" + prop + "']")
                        dom.innerText = watchers[prop];
                        dom.value = watchers[prop];
                        //重新监听
                        domeve && document.addEventListener('DOMCharacterDataModified', than.element, false);
                        domeve && document.addEventListener('DOMNodeInserted', than.element, false);
                    }
                });
            });
        },

        element: function (e) {
            //dom的修改触发JS变量的修改
            // console.log(e.newValue, e.prevValue, e.path);
            const attrs = e.target.parentElement.attributes;
            for (let i = 0; i < attrs.length; i++) {
                const attr = attrs[i];
                if (ng === attr.nodeName) {
                    watchscope[attr.nodeValue] = e.target.nodeValue;
                }
            }
        },
        domevent: function () {
            domeve = true;
            //绑定DOM的修改关联
            document.addEventListener('DOMCharacterDataModified', this.element, false);
            document.addEventListener('DOMNodeInserted', this.element, false);
        },
        inputevent: function () {
            //绑定input表单的修改关联
            var input = document.querySelectorAll("input["+ng+"]")
            for (var k in input) {
                input[k].oninput = function (e) {
                    watchscope[e.target.attributes[ng].nodeValue] = e.target.value;
                }
            }

        }
    }

}